Djangoで組織とユーザーの権限の管理をやってみる #devio2022
クラスメソッドオンラインイベントDevelopersIO 2022で「Djangoで組織とユーザーの権限の管理をやってみる」というテーマで話した内容をご紹介します。
動画
スライド
GitHub
https://github.com/seiichi1101/devio2022
概要
やりたいこと
- ユーザーの登録ができる
- 組織の登録ができる
- ユーザーは複数の組織に所属することができる
- ユーザーは所属外の組織情報にはアクセスできない
- ユーザーは所属する組織毎に権限を与えられる
- 権限は Admin、Editor、Viewer のいずれかとする
- 権限に応じたアクセス制御が可能とする
ERD
セットアップ
GitHubのブランチを参考にしてください。
ユーザーと組織の権限管理について
「ユーザーと組織の権限管理」についてどういったアプローチがあるのか考察
モデル設計
Djangoでユーザーと組織の権限を権限管理するにはいくつかパターンが考えられます。
1. 組み込みのGroupとPermissionsを利用する方法
まず1つ目が組み込みで用意されているGroup
とPermissions
モデルをそのまま利用する方法です。Django Permissions
Djangoでは、django.contrib.auth
が INSTALLED_APPS
設定にリストされていると、定義された各Djangoモデルに対して、add
, change
, delete
, view
という4つの デフォルトパーミッションを作成してくれます。
このPermissions
はUser
やGroup
に割り当てることができ、Djangoの権限管理に利用できます。
これをそのまま利用できそうに思えますが、今回のような組織の中に複数の権限グループ[Admin, Editor, Viewer]があり権限グループにユーザーを割り当てるということはデフォルトパーミッションでは実現できません。
仮にやる場合は、Group
もしくはPermissions
モデルを拡張する必要があります。
テーブル数が増えず複雑になりにくいですが、Djangoがそもそも期待している使い方と異なるため少し面倒です。
2. 3rd Partyのライブラリを利用する方法
2つ目が、3rd Partyのライブラリを利用する方法です。
django-organizationというライブラリを使えば、組織管理者の作成や組織への招待など色々な機能が提供されています。
一方で、必要以上の機能があることで混乱したり、今回のような複数の権限グループを作成したい場合にはいずれにせよカスタマイズが必要になります。
3. 自分で必要なモデルと機能を実装する方法
3つ目が、自分でモデルを作成する方法です。
具体的にはER図に記載しているOrganization
, Group
, Role
のモデルを自作する方法です。
必要な機能を自分で実装することで、必要以上に複雑にならず、モデルの拡張もしやすくなります。
懸念点としては、コード量やテーブル数が増えたり、組み込みモデルとの使い分けを明確にする必要があり、管理が手間が増えます。
1,2は冒頭に紹介した要件にフィットしなかったため、今回は3つ目の方法を使います。
ライブラリを使った権限管理
次に、Djangoで権限管理をするパターンをいくつか紹介します。
前述でも説明した通り、権限管理には既存のGroup
とPermissions
を利用する方法がありますが、今回は既存のモデルは利用しないため別の方法を考えます。
Djangoでは権限管理のため有名なライブラリがいくつか存在するため、今回はそちらのいずれかを利用したいと思います。
3-1. django-guardian
1つ目がdjango-guardianです。
こちらのライブラリでは、既存のPermissions
を拡張することでインスタンスレベルでのアクセス制御する提供しています。
Group毎に権限を与えることはできますが、[Admin、Editor、Viewer]みたいな汎用的な権限のまとまりを設定することはできず、都度Permissions
を付与する必要があるため、複数組織にまたがって同じような権限を設定する際には少し面倒です。
3-2. django-role-permissions
2つ目がdjango-role-permissionsです。
こちらも前述のdjango-organization
とおなじく、既存のPermissions
を拡張することでインスタンスレベルでのアクセス制御を提供しています。
が、同じく組織にまたがった汎用的な権限のまとまりを設定することは難しいです。
3-3. django-rules
3つ目が、django-rulesです。
前述の2つとの違いは、権限の管理にデータベースモデルを使用しない点です。
事前に定義したコードをベースにアクセスコントロールを設定できるため、カスタマイズしやすく、今回のような汎用的な権限のまとまりを設定することも可能です。
ただ、既存のPermissionsモデルを利用しないため、コード量は増えます。
今回は権限グループのまとまりをうまく表現出来そうなdjango-rules
を採用します。
ユーザーと組織の実装
GitHubのブランチを参考にしてください。
権限の実装
GitHubのブランチを参考にしてください。
- ref
まとめ
いかかでしょうか。
どなたかの役に立てば幸いです。
また、もし他にいい方法を知っている方いれば是非教えてほしいです。